﻿using System;
using System.IO;
using System.Net;
using System.Linq;
using System.Text;
using System.Activities;
using System.Activities.Expressions;
using System.Activities.Presentation.PropertyEditing;
using System.Activities.Statements;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO.Packaging;
using ICSharpCode.SharpZipLib.Zip;

namespace Vision.Core.ActivityComponents.IO.Compression
{
    /// <summary>
    /// 
    /// </summary>
    [System.ComponentModel.Designer(typeof(ZipStreamArchiveDesigner))]
    public class ZipStreamArchive : NativeActivity
    {
        /// <summary>
        /// 
        /// </summary>
        internal MemoryStream FileStream { get; set; }

        /// <summary>
        /// 
        /// </summary>
        internal ZipOutputStream ZipStream { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Browsable(false)]
        [DefaultValue(null)]
        public Activity Body { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public InArgument<byte[]> ZipDataIn { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public OutArgument<byte[]> ZipDataOut { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [DefaultValue(5)]
        public InArgument<int> CompressionLevel { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        protected override void Execute(NativeActivityContext context)
        {
            if (this.Body != null){
                this.FileStream = new MemoryStream();
                if (context.GetValue(this.ZipDataIn) != null){
                    this.FileStream = new MemoryStream(context.GetValue(this.ZipDataIn));
                }                
                this.ZipStream = new ZipOutputStream(this.FileStream);
                this.ZipStream.SetLevel(context.GetValue(this.CompressionLevel));
                context.Properties.Add("60D19250-2D72-11E0-BAE7-4BCBDFD72085", this.ZipStream);
                context.ScheduleActivity(this.Body, this.OnChildActivityCompleted);
            }  
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="completedInstance"></param>
        private void OnChildActivityCompleted(NativeActivityContext context, ActivityInstance completedInstance)
        {
            context.Properties.Remove("60D19250-2D72-11E0-BAE7-4BCBDFD72085");
            this.ZipStream.Finish();
            this.ZipStream.Flush();
            this.FileStream.Flush();

            context.SetValue(this.ZipDataOut, this.FileStream.ToArray());
            
            this.ZipStream.Close();
            this.FileStream.Close();
            this.ZipStream.Dispose();
            this.FileStream.Dispose();
        }        
    }
}
